//
//  FindWordPlayVC.swift
//  Game
//
//  Created by woniu on 2025/9/4.
//

import UIKit

class FindWordPlayVC: BaseVC, UITableViewDataSource, UITableViewDelegate {
    public var gameModel: GameModel!
    public var configModel = FindeWordConfig()
    
    // 卡片层，包含所有单词卡片（作为被遮罩的内容）
    private let cardsContainer = UIView()
    private var cardViews: [UIView] = []
    private var originalTransforms: [CGAffineTransform] = []
    // 左侧单词列表宽度固定 100
    private let leftListWidth: CGFloat = 100
    private let wordListView = UITableView(frame: .zero, style: .plain)
    private var selectedIndex: Int? = nil
    
    // 遮罩层 - 只显示圆形区域
    private let maskLayer = CAShapeLayer()
    private let magnifierView = UIView()
    //遮罩半径
    private let magnifierRadius: CGFloat = 80
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let dic = gameModel.jsonData.toDic()
        configModel = FindeWordConfig.deserialize(from: dic) ?? FindeWordConfig()
        setupUI()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        // 布局左侧列表和卡片容器：列表固定宽 100，卡片容器占右侧剩余空间
        wordListView.frame = CGRect(x: 0, y: 70, width: leftListWidth, height: view.bounds.height-70)
        cardsContainer.frame = CGRect(x: leftListWidth, y: 0, width: max(0, view.bounds.width - leftListWidth), height: view.bounds.height)
        // 初次或旋转后重新布局卡片（保留已有位置的话可以注释掉）
        if cardViews.isEmpty {
            createCards()
            layoutCardsRandomly()
            // 初始遮罩在屏幕中心（转换到 cardsContainer 坐标系）
            let centerInView = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
            updateMask(at: cardsContainer.convert(centerInView, from: view))
        }
        // 强制放大镜位置不进入左侧列表区域
        let half = magnifierRadius
        var center = magnifierView.center
        let minX = leftListWidth + half
        center.x = max(minX, min(view.bounds.width - half, center.x))
        center.y = max(half, min(view.bounds.height - half, center.y))
        magnifierView.center = center
    }
    
    // MARK: - UI
    private func setupUI() {
        view.backgroundColor = .black
        
        // 左侧单词列表（固定宽度）
        wordListView.dataSource = self
        wordListView.delegate = self
        wordListView.tableFooterView = UIView()
        wordListView.backgroundColor = UIColor(white: 0.06, alpha: 1)
        wordListView.separatorStyle = .none
        wordListView.register(UITableViewCell.self, forCellReuseIdentifier: "WordCell")
        view.addSubview(wordListView)
        
        // cardsContainer 放在 view 上，用作被遮罩的图层（右侧）
        cardsContainer.frame = CGRect(x: leftListWidth, y: 0, width: max(0, view.bounds.width - leftListWidth), height: view.bounds.height)
        cardsContainer.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(cardsContainer)
        
        // maskLayer 默认覆盖整个 container（但我们会用一个圆形 path 替换它）
        maskLayer.fillRule = .evenOdd
        cardsContainer.layer.mask = maskLayer
        
        // magnifierView 是用户可拖拽的圆形指示器
        magnifierView.frame = CGRect(x: 0, y: 0, width: magnifierRadius * 2, height: magnifierRadius * 2)
        magnifierView.center = view.center
        magnifierView.backgroundColor = .clear
        magnifierView.layer.borderColor = UIColor.white.withAlphaComponent(0.9).cgColor
        magnifierView.layer.borderWidth = 2
        magnifierView.layer.cornerRadius = magnifierRadius
        magnifierView.layer.masksToBounds = true
        magnifierView.isUserInteractionEnabled = true
        magnifierView.alpha = 0.95
        // 给放大镜一个轻微阴影，以便在黑色背景上更显眼
        magnifierView.layer.shadowColor = UIColor.black.cgColor
        magnifierView.layer.shadowOpacity = 0.4
        magnifierView.layer.shadowRadius = 4
        magnifierView.layer.shadowOffset = CGSize(width: 0, height: 2)
        view.addSubview(magnifierView)
        
        // 添加拖拽手势
        let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
        magnifierView.addGestureRecognizer(pan)
        
        
        let sortButton = UIButton(type: .system)
        sortButton.setImage(UIImage(named: "重置_刷新"), for: .normal)
        sortButton.tintColor = .white
        sortButton.imageView?.contentMode = .scaleAspectFit
        sortButton.addTarget(self, action: #selector(onReset), for: .touchUpInside)
        self.view.addSubview(sortButton)
        sortButton.snp.makeConstraints { make in
            make.top.equalTo(backButton.snp.top)
            make.right.equalToSuperview()
            make.width.equalTo(30)
            make.height.equalTo(30)
        }
        
        let showOrHiddenButton = UIButton(type: .system)
        showOrHiddenButton.backgroundColor = .black
        showOrHiddenButton.setImage(UIImage(named: "月亮"), for: .normal)
        showOrHiddenButton.setImage(UIImage(systemName: "sun.max"), for: .selected)
        showOrHiddenButton.tintColor = .white
        showOrHiddenButton.imageView?.contentMode = .scaleAspectFit
        showOrHiddenButton.addTarget(self, action: #selector(showOrHidden(sender:)), for: .touchUpInside)
        self.view.addSubview(showOrHiddenButton)
        showOrHiddenButton.snp.makeConstraints { make in
            make.top.equalTo(backButton.snp.top)
            make.right.equalTo(sortButton.snp.left).offset(-50)
            make.width.equalTo(30)
            make.height.equalTo(30)
        }
    }
    
    @objc func showOrHidden(sender:UIButton){
        sender.isSelected = !sender.isSelected
        if sender.isSelected{
            cardsContainer.layer.mask = nil
            magnifierView.isHidden = true
        }else{
            cardsContainer.layer.mask = maskLayer
            magnifierView.isHidden = false
        }
    }
    
    //重新排列
    @objc func onReset(){
        guard !cardViews.isEmpty else { return }
        let safeInset: CGFloat = 20
        let bounds = cardsContainer.bounds.insetBy(dx: safeInset, dy: safeInset)
        
        UIView.animate(withDuration: 0.36, delay: 0, options: .curveEaseInOut, animations: {
            for card in self.cardViews {
                // 为避免在非 identity transform 下设置 frame 导致尺寸/缩放累积，先重置 transform
                card.transform = CGAffineTransform.identity
                
                let maxX = bounds.maxX - card.bounds.width
                let maxY = bounds.maxY - card.bounds.height
                let x: CGFloat
                let y: CGFloat
                if maxX <= bounds.minX { x = bounds.minX } else { x = CGFloat.random(in: bounds.minX...maxX) }
                if maxY <= bounds.minY { y = bounds.minY } else { y = CGFloat.random(in: bounds.minY...maxY) }
                // 使用 frame.origin 更新位置（在 identity transform 下安全）
                card.frame.origin = CGPoint(x: x, y: y)
                // 随机小幅旋转以增加重新排列的感觉（将作为新的基线 transform）
                let angleDeg = CGFloat.random(in: -10...10)
                let angle = angleDeg * (.pi / 180)
                card.transform = CGAffineTransform(rotationAngle: angle)
            }
        }, completion: { _ in
            // 更新保存的原始 transform
            self.originalTransforms = self.cardViews.map { $0.transform }
        })
    }
    
    // MARK: - Cards
    private func createCards() {
        for itemView in cardViews{itemView.removeFromSuperview()}
        cardViews.removeAll()
        originalTransforms.removeAll()
        
        for word in configModel.inputContentList {
            let card = makeCard(for: word)
            cardViews.append(card)
            cardsContainer.addSubview(card)
            // 保存初始 transform，供选中/恢复使用
            originalTransforms.append(card.transform)
        }
    }
    
    private func makeCard(for word: String) -> UIView {
        let lab = UILabel()
        lab.textAlignment = .center
        lab.text = word
        lab.backgroundColor = randomLightColor()
        lab.textColor = .black
        lab.font = UIFont.boldSystemFont(ofSize: 28)
        
        // 计算文本大小并向上取整，避免子像素问题
        let maxSize = CGSize(width: max(100, cardsContainer.bounds.width - 40), height: CGFloat.greatestFiniteMagnitude)
        let fitted = lab.sizeThatFits(maxSize)
        let textW = ceil(fitted.width)
        let textH = ceil(fitted.height)
        
        // 内边距
        let paddingX: CGFloat = 10
        let paddingY: CGFloat = 10
        let minW: CGFloat = 60
        let minH: CGFloat = 36
        
        let contentW = max(minW, textW + paddingX * 2)
        let contentH = max(minH, textH + paddingY * 2)
        lab.frame =  CGRect(x: 0, y: 0, width: contentW, height: contentH)
        lab.layer.cornerRadius = 5
        lab.layer.masksToBounds = true
        
        let angleDeg = CGFloat.random(in: -10...10)
        let angle = angleDeg * (.pi / 180)
        lab.transform = CGAffineTransform(rotationAngle: angle)
        return lab
    }
    
    private func layoutCardsRandomly() {
        guard !cardViews.isEmpty else { return }
        let safeInset: CGFloat = 20
        let bounds = cardsContainer.bounds.insetBy(dx: safeInset, dy: safeInset)
        
        var placedFrames: [CGRect] = []
        let padding: CGFloat = 8          // 卡片之间的最小间距
        let maxAttempts = 120            // 每张卡片的随机尝试次数
        
        for card in cardViews {
            // 确保使用当前 card 的 size（前面已 sizeToFit）
            let cardSize = card.bounds.size
            var placed = false
            
            // 随机放置重试
            for _ in 0..<maxAttempts {
                let maxX = bounds.maxX - cardSize.width
                let maxY = bounds.maxY - cardSize.height
                guard maxX > bounds.minX && maxY > bounds.minY else { break }
                let x = CGFloat.random(in: bounds.minX...maxX)
                let y = CGFloat.random(in: bounds.minY...maxY)
                let candidate = CGRect(origin: CGPoint(x: x, y: y), size: cardSize)
                
                var intersects = false
                for f in placedFrames {
                    // 扩展已有框以保留间距（避免紧贴）
                    if candidate.insetBy(dx: -padding, dy: -padding).intersects(f) {
                        intersects = true
                        break
                    }
                }
                if !intersects {
                    card.frame = candidate
                    placedFrames.append(candidate)
                    placed = true
                    break
                }
            }
            
            // 如果随机多次失败，使用螺旋或线性回退放置
            if !placed {
                // 螺旋搜索：从容器中心向外找可放置位置
                let centerOrigin = CGPoint(x: bounds.midX - cardSize.width / 2, y: bounds.midY - cardSize.height / 2)
                var found = false
                var angle: CGFloat = 0
                let angleStep: CGFloat = 0.5
                let radiusStep: CGFloat = 12.0
                for _ in 0..<800 {
                    let radius = radiusStep * angle
                    let cx = centerOrigin.x + cos(angle) * radius
                    let cy = centerOrigin.y + sin(angle) * radius
                    let candidateOrigin = CGPoint(x: min(max(bounds.minX, cx), bounds.maxX - cardSize.width),
                                                  y: min(max(bounds.minY, cy), bounds.maxY - cardSize.height))
                    let candidate = CGRect(origin: candidateOrigin, size: cardSize)
                    var intersects = false
                    for f in placedFrames {
                        if candidate.insetBy(dx: -padding, dy: -padding).intersects(f) { intersects = true; break }
                    }
                    if !intersects {
                        card.frame = candidate
                        placedFrames.append(candidate)
                        found = true
                        break
                    }
                    angle += angleStep
                }
                // 最后兜底：按行堆叠（保证不会超出 bounds）
                if !found {
                    let row = placedFrames.count
                    let x = bounds.minX
                    let y = bounds.minY + CGFloat(row) * (cardSize.height + padding)
                    let finalY = min(y, bounds.maxY - cardSize.height)
                    let finalFrame = CGRect(origin: CGPoint(x: x, y: finalY), size: cardSize)
                    card.frame = finalFrame
                    placedFrames.append(finalFrame)
                }
            }
        }
    }
    
    // MARK: - Mask handling
    private func updateMask(at center: CGPoint, animated: Bool = false) {
        // maskLayer 的坐标系与 cardsContainer 一致
        maskLayer.frame = cardsContainer.bounds
        let radius = magnifierRadius
        let circleRect = CGRect(x: center.x - radius, y: center.y - radius, width: radius * 2, height: radius * 2)
        let circlePath = UIBezierPath(ovalIn: circleRect)
        
        if animated {
            let anim = CABasicAnimation(keyPath: "path")
            anim.duration = 0.12
            anim.timingFunction = CAMediaTimingFunction(name: .easeOut)
            anim.fromValue = maskLayer.path
            anim.toValue = circlePath.cgPath
            maskLayer.add(anim, forKey: "path")
        }
        
        maskLayer.path = circlePath.cgPath
        maskLayer.fillRule = .nonZero
    }
    
    @objc private func handlePan(_ g: UIPanGestureRecognizer) {
        let translation = g.translation(in: view)
        switch g.state {
        case .began, .changed:
            var center = magnifierView.center
            center.x += translation.x
            center.y += translation.y
            // 限制在可见区域内（避免拖出屏幕）
            let half = magnifierRadius
            // 不允许进入左侧列表区域
            let minX = leftListWidth + half
            center.x = max(minX, min(view.bounds.width - half, center.x))
            center.y = max(half, min(view.bounds.height - half, center.y))
            magnifierView.center = center
            g.setTranslation(.zero, in: view)
            updateMask(at: cardsContainer.convert(center, from: view), animated: false)
        default:
            break
        }
    }
    
    // MARK: - Helpers
    private func randomLightColor() -> UIColor {
        // 生成浅色系（低饱和度，高亮度）
        let hue = CGFloat.random(in: 0...1)
        let saturation = CGFloat.random(in: 0.2...0.45)
        let brightness = CGFloat.random(in: 0.9...0.98)
        return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1)
    }
    
    // MARK: - TableView DataSource / Delegate
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return configModel.inputContentList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "WordCell", for: indexPath)
        let word = configModel.inputContentList[indexPath.row]
        cell.textLabel?.text = word
        cell.textLabel?.numberOfLines = 2
        cell.textLabel?.font = UIFont.systemFont(ofSize: 14, weight: .semibold)
        cell.textLabel?.textColor = UIColor.white
        cell.backgroundColor = UIColor.clear
        cell.selectionStyle = .none
        
        // 选中样式
        if indexPath.row == selectedIndex {
            cell.contentView.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.25)
            cell.textLabel?.textColor = UIColor.white
        } else {
            cell.contentView.backgroundColor = UIColor.clear
            cell.textLabel?.textColor = UIColor(white: 0.9, alpha: 1)
        }
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // 更新选中状态并刷新列表
        let prev = selectedIndex
        selectedIndex = indexPath.row
        var paths: [IndexPath] = [indexPath]
        if let p = prev { paths.append(IndexPath(row: p, section: 0)) }
        tableView.reloadRows(at: paths, with: .automatic)
        
        // 高亮对应卡片：将对应卡片放大并添加白色边框
        highlightCard(at: indexPath.row)
    }
    
    private func highlightCard(at index: Int) {
        guard index >= 0 && index < cardViews.count else { return }
        // 重置其他卡片样式
        for (i, card) in cardViews.enumerated() {
            if i == index {
                // 动画放大并加边框
                UIView.animate(withDuration: 0.18) {
                    let base = (i < self.originalTransforms.count) ? self.originalTransforms[i] : card.transform
                    card.transform = base.scaledBy(x: 1.08, y: 1.08)
                    card.layer.borderWidth = 2
                    card.layer.borderColor = UIColor.red.cgColor
                }
                // 同时把遮罩移动到卡片中心
                let cardCenter = CGPoint(x: card.frame.midX, y: card.frame.midY)
                updateMask(at: cardCenter, animated: true)
                // 同步移动 magnifierView 可视化位置（转换到主 view 坐标）
                let mainCenterUnclamped = cardsContainer.convert(cardCenter, to: view)
                let half = self.magnifierRadius
                let minX = self.leftListWidth + half
                let clampedX = max(minX, min(self.view.bounds.width - half, mainCenterUnclamped.x))
                let clampedY = max(half, min(self.view.bounds.height - half, mainCenterUnclamped.y))
                let mainCenter = CGPoint(x: clampedX, y: clampedY)
                UIView.animate(withDuration: 0.18) {
                    self.magnifierView.center = mainCenter
                }
            } else {
                UIView.animate(withDuration: 0.18) {
                    // 恢复到原旋转（注意：之前 transform 包含旋转；这里尝试仅缩放回 1）
                    let base = (i < self.originalTransforms.count) ? self.originalTransforms[i] : CGAffineTransform.identity
                    card.transform = base
                    card.layer.borderWidth = 0
                }
            }
        }
    }
}
